import React, { useCallback, useState, useEffect, useMemo, useRef } from 'react';
import { Tabs, Radio, Button, Icon } from 'antd';
import _ from 'lodash';
import arrayMove from 'array-move';
import SmartModal from '@/components/smartmodal';
import { deepCopy4JSON, MODAL_HEADER_HEIGHT, MODAL_PADDING_HEIGHT, MODAL_FOOTER_HEIGHT } from '@/utils/utils';
import { UiContent, SortableList, SaveAsModal, SearchFieldTransfer } from './components';
import {
  SupportFilterField,
  SupportOrderField,
  View,
  SearchField,
  OrderField,
  UiConfigProps,
} from '@/components/searchform/interface';
import styles from './index.less';
import { CompanyViewAuth } from './components/SaveAsModal';
import { UISchema } from 'gantd/lib/schema-form';
const { TabPane } = Tabs;

enum TabsEnum {
  search,
  order,
  uiConfig,
}

export interface SaveAsDataProps {
  values: { name: string; isDefault: boolean };
  searchFields: SearchField[];
  orderFields: OrderField[];
  uiConfig: UiConfigProps;
}

export interface ConfigProps {
  singleView: boolean;
  visible: boolean;
  setVisible: (visible: boolean) => void;
  activeView: View;
  viewSelector: any;
  supportFilterFields: SupportFilterField[];
  supportOrderFields: SupportOrderField[];
  configModalSize?: any;
  loading?: boolean;
  saveAsLoading?: boolean;
  onSave?: (view: any, cb: () => void) => void;
  onSingleViewSave?: (view: any, cb: () => void) => void;
  onSaveAs?: (data: SaveAsDataProps, cb: () => void) => void;
  isCompatibilityMode: boolean;
  fieldTransfer: boolean;
  hideOrderField: boolean;
  systemViews: View[];
  customViews: View[];
  companyViews: View[];
  showDisplayConfig: boolean;
  companyViewAuth: CompanyViewAuth;
  uiSchema: UISchema;
}

const setLockKey = function (arr: Array<any>) {
  return _.map(arr, (item, key) => {
    return { ...item, lockKey: key };
  });
};

/**
 * 配置弹框
 * @param props
 */
export default function Config(props: ConfigProps) {
  const {
    singleView,
    visible,
    setVisible,
    activeView,
    viewSelector,
    supportFilterFields,
    supportOrderFields,
    configModalSize,
    loading,
    saveAsLoading,
    onSave,
    onSingleViewSave,
    onSaveAs,
    isCompatibilityMode,
    fieldTransfer,
    hideOrderField,
    systemViews,
    companyViews,
    customViews,
    showDisplayConfig,
    companyViewAuth,
    uiSchema,
  } = props;
  const { isSystem } = activeView;
  // 控制配置弹框显隐
  const [saveAsVisible, setSaveAsVisible] = useState<boolean>(false);
  // 控制弹框中显示哪个配置tab
  const [tabsKey, setTabsKey] = useState<string>(TabsEnum[0]);
  // 记录变化的查询字段列表
  const [tempSearchFields, setTempSearchFields] = useState<SearchField[]>([]);
  // 记录变化的排序字段列表
  const [tempOrderFields, setTempOrderFields] = useState<OrderField[]>([]);
  // 记录变化的ui配置
  const [tempUiConfig, setTempUiConfig] = useState<UiConfigProps>({});
  // 记录变化后查询字段长度
  const [searchMaxLockKey, setSearchMaxLockKey] = useState<number>(0);
  // 记录变化后排序字段长度
  const [orderMaxLockKey, setOrderMaxLockKey] = useState<number>(0);
  // 以ref形式记录变化的查询字段列表
  const tempSearchRef = useRef(tempSearchFields);
  // 以ref形式记录变化的排序字段列表
  const tempOrderRef = useRef(tempOrderFields);
  // 以ref形式记录变化的ui配置
  const tempUiRef = useRef(tempUiConfig);
  // 控制配置弹框的尺寸
  const [modalSize, setModalSize] = useState({ ...configModalSize });
  // 记录变化的查询字段列表(穿梭场景)
  const [transerSearchFields, setTransferSearchFields] = useState<SearchField[]>([]);

  const contentHeight = useMemo(() => {
    const { height } = modalSize;
    return height - MODAL_HEADER_HEIGHT - 2 * MODAL_PADDING_HEIGHT - MODAL_FOOTER_HEIGHT - 34;
  }, [modalSize]);

  const titleElement = useMemo(
    () => (
      <div className={styles.configHeaderTitle}>
        <Icon className={styles.configHeaderTitleIcon} type="setting" />
        <span>{tr('查询视图配置')}</span>
        {!singleView && viewSelector}
      </div>
    ),
    [viewSelector, singleView],
  );

  // 某个查询字段调整
  const onSearchChange = useCallback((value, index, isMain) => {
    const { label, key } = value;
    let data = deepCopy4JSON(tempSearchRef.current);
    if (isMain) {
      data[index].fieldName = key;
      delete data[index].operator;
    } else {
      data[index].operator = key;
    }
    setTempSearchFields(data);
  }, []);

  // 某个排序字段调整
  const onOrderChange = useCallback((value, index, isMain) => {
    const { label, key } = value;
    let data = deepCopy4JSON(tempOrderRef.current);
    data =
      data.length === 0
        ? [
            {
              fieldName: tr('请选择'),
              orderType: 'ASC',
            },
          ]
        : data;
    if (isMain) {
      data[index].fieldName = key;
      data[index].orderType = 'DESC';
    } else {
      data[index].orderType = key;
    }
    setTempOrderFields(data);
  }, []);

  // ui配置调整
  const onUiConfigChange = useCallback(
    (key, value) => {
      setTempUiConfig({ ...tempUiRef.current, [key]: value });
    },
    [tempUiRef],
  );

  // 创建新的查询/排序字段
  const onCreate = useCallback(
    (type, index) => {
      if (type == TabsEnum[0]) {
        let data = deepCopy4JSON(tempSearchRef.current);
        data.splice(index + 1, 0, { lockKey: searchMaxLockKey } as any);
        setTempSearchFields(data);
        setSearchMaxLockKey(searchMaxLockKey + 1);
      } else {
        let data = deepCopy4JSON(tempOrderRef.current);
        data.splice(index + 1, 0, {
          orderType: 'DESC',
          lockKey: orderMaxLockKey,
        } as any);
        setTempOrderFields(data);
        setOrderMaxLockKey(orderMaxLockKey + 1);
      }
    },
    [searchMaxLockKey, orderMaxLockKey],
  );

  // 移除某个查询/排序字段
  const onRemove = useCallback((type, index) => {
    let setFn = type == TabsEnum[0] ? setTempSearchFields : setTempOrderFields;
    let data = deepCopy4JSON(type == TabsEnum[0] ? tempSearchRef.current : tempOrderRef.current);
    if (data.length == 1) return;
    data.splice(index, 1);
    setFn(data as any);
  }, []);

  // 查询/排序字段拖拽完成
  const onSortEnd = useCallback((type, { oldIndex, newIndex }) => {
    if (type == TabsEnum[0]) {
      setTempSearchFields([...arrayMove(tempSearchRef.current, oldIndex, newIndex)]);
    } else {
      setTempOrderFields([...arrayMove(tempOrderRef.current, oldIndex, newIndex)]);
    }
  }, []);

  // 关闭配置弹框
  const changeModalStatus = useCallback(() => {
    setVisible(false);
  }, []);

  // 获取所有的查询和排序字段
  const getAllFields = useCallback(() => {
    let searchFields = _.chain(tempSearchRef.current)
      .map((i) => _.omit(i, 'lockKey'))
      .filter((i) => !_.isEmpty(i))
      .uniqWith(_.isEqual)
      .value();
    let orderFields = _.chain(tempOrderRef.current)
      .map((i) => _.omit(i, 'lockKey'))
      .filter((i) => i.fieldName != undefined)
      .uniqWith(_.isEqual)
      .value();
    return { searchFields, orderFields };
  }, []);

  // 处理保存
  const handleSave = useCallback(() => {
    if (isSystem && !singleView) return;
    const { searchFields, orderFields } = getAllFields();
    const newView = {
      ...activeView,
      panelConfig: {
        ...activeView.panelConfig,
        searchFields: fieldTransfer ? transerSearchFields : searchFields,
        orderFields,
        uiConfig: tempUiRef.current,
      },
    };
    delete newView.isSystem;
    let cb = () => {
      setVisible(false);
    };
    if (singleView) {
      if (_.isEqual(activeView, newView)) return;
      onSingleViewSave && onSingleViewSave(newView, cb);
      return;
    }
    onSave && onSave(newView, cb);
  }, [onSave, isSystem, fieldTransfer, transerSearchFields, singleView, activeView]);

  // 处理另存为
  const handleSaveAs = useCallback(
    (values) => {
      const { searchFields, orderFields } = getAllFields();
      let cb = () => {
        setSaveAsVisible(false);
        setVisible(false);
      };
      onSaveAs &&
        onSaveAs(
          {
            values,
            searchFields: fieldTransfer ? transerSearchFields : searchFields,
            orderFields,
            uiConfig: tempUiRef.current,
          },
          cb,
        );
    },
    [onSaveAs, transerSearchFields, fieldTransfer],
  );

  const onModalSizeChange = useCallback((width: number, height: number) => {
    setModalSize({ width, height });
  }, []);

  // 更新内部state的实现
  const updateConfig = useCallback(
    (searchFields: SearchField[], orderFields: OrderField[], uiConfig: UiConfigProps) => {
      setTempSearchFields(setLockKey(searchFields));
      setTempOrderFields(setLockKey(orderFields));
      setTempUiConfig(uiConfig);
      setSearchMaxLockKey(searchFields.length);
      setOrderMaxLockKey(orderFields.length);
      setTransferSearchFields(searchFields);
    },
    [],
  );

  useEffect(() => {
    tempSearchRef.current = tempSearchFields;
  }, [tempSearchFields]);

  useEffect(() => {
    tempOrderRef.current = tempOrderFields;
  }, [tempOrderFields]);

  useEffect(() => {
    tempUiRef.current = tempUiConfig;
  }, [tempUiConfig]);

  // 当前激活的视图变化时，更新内部的state
  useEffect(() => {
    const {
      panelConfig: { searchFields, orderFields = [], uiConfig = {} },
    } = activeView;
    visible && updateConfig(searchFields, orderFields, uiConfig);
  }, [activeView, visible]);

  return (
    <>
      <SmartModal
        id="searchFormConfigModal"
        itemState={configModalSize}
        visible={visible}
        title={titleElement}
        onCancel={changeModalStatus}
        isModalDialog
        onSizeChange={onModalSizeChange}
        zIndex={1007}
        footer={
          <div>
            <Button
              size="small"
              icon="close-circle"
              onClick={() => {
                setVisible(false);
              }}
            >
              {tr('取消')}
            </Button>
            {!singleView && (
              <Button
                size="small"
                icon="diff"
                disabled={fieldTransfer && transerSearchFields.length === 0 ? true : false}
                onClick={() => {
                  setSaveAsVisible(true);
                }}
              >
                {tr('另存为')}
              </Button>
            )}
            <Button
              size="small"
              type="primary"
              icon="save"
              loading={loading}
              onClick={handleSave}
              disabled={(isSystem && !singleView) || (fieldTransfer && transerSearchFields.length === 0)}
            >
              {tr('保存')}
            </Button>
          </div>
        }
      >
        <div className={styles.configContent}>
          <div className={styles.RadioGroupTabs}>
            <Radio.Group
              defaultValue={tabsKey}
              buttonStyle="solid"
              size="small"
              onChange={(e) => setTabsKey(e.target.value)}
            >
              <Radio.Button value={TabsEnum[0]}>{tr('字段配置')}</Radio.Button>
              {!hideOrderField && <Radio.Button value={TabsEnum[1]}>{tr('结果排序规则')}</Radio.Button>}
              {showDisplayConfig && <Radio.Button value={TabsEnum[2]}>{tr('显示配置')}</Radio.Button>}
            </Radio.Group>
          </div>
          <Tabs activeKey={tabsKey} className={styles.contentTabs}>
            <TabPane tab={tr('字段配置')} key={TabsEnum[0]}>
              {fieldTransfer ? (
                <SearchFieldTransfer
                  height={contentHeight}
                  supportFilterFields={supportFilterFields}
                  searchFields={transerSearchFields}
                  showOperatorColumn={!isCompatibilityMode}
                  onChange={setTransferSearchFields}
                  uiSchema={uiSchema}
                />
              ) : (
                <SortableList
                  helperClass={styles.sortableHelper}
                  useDragHandle
                  supportFields={supportFilterFields}
                  fields={tempSearchFields}
                  type={TabsEnum[0]}
                  onSelectChange={onSearchChange}
                  onCreate={onCreate}
                  onRemove={onRemove}
                  onSortEnd={onSortEnd.bind(null, TabsEnum[0])}
                  isCompatibilityMode={isCompatibilityMode}
                />
              )}
            </TabPane>
            {!hideOrderField && (
              <TabPane tab={tr('排序配置')} key={TabsEnum[1]}>
                <SortableList
                  helperClass={styles.sortableHelper}
                  useDragHandle
                  supportFields={supportOrderFields}
                  fields={tempOrderFields}
                  type={TabsEnum[1]}
                  onSelectChange={onOrderChange}
                  onCreate={onCreate}
                  onRemove={onRemove}
                  onSortEnd={onSortEnd.bind(null, TabsEnum[1])}
                  isCompatibilityMode={isCompatibilityMode}
                />
              </TabPane>
            )}
            <TabPane tab={tr('显示配置')} key={TabsEnum[2]}>
              <UiContent uiConfig={tempUiConfig} onChange={onUiConfigChange} />
            </TabPane>
          </Tabs>
        </div>
      </SmartModal>
      <SaveAsModal
        loading={saveAsLoading}
        visible={saveAsVisible}
        onSubmit={handleSaveAs}
        viewType={activeView.viewType}
        companyViews={companyViews}
        customViews={customViews}
        onCancel={() => {
          setSaveAsVisible(false);
        }}
        companyViewAuth={companyViewAuth}
      />
    </>
  );
}
